<!DOCTYPE html>
<html>
<head>
<title>Relativity Frames Diagram</title>
</head>
<body>
<canvas id="relativityCanvas" width="600" height="300" style="border:1px solid #eee;"></canvas>
<script>
// This script draws a physics diagram illustrating relative motion between two inertial frames, S and S'.
// It is intended to replicate the provided image using the HTML5 Canvas API.

const canvas = document.getElementById('relativityCanvas');
const ctx = canvas.getContext('2d');

// Style settings
ctx.lineWidth = 1.5;
ctx.strokeStyle = 'black';
ctx.fillStyle = 'black';
ctx.font = 'italic 22px "Times New Roman"';

// Helper function to draw an arrow
function drawArrow(x1, y1, x2, y2, arrowSize = 8) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();

    const angle = Math.atan2(y2 - y1, x2 - x1);
    ctx.beginPath();
    ctx.moveTo(x2, y2);
    ctx.lineTo(x2 - arrowSize * Math.cos(angle - Math.PI / 6), y2 - arrowSize * Math.sin(angle - Math.PI / 6));
    ctx.lineTo(x2 - arrowSize * Math.cos(angle + Math.PI / 6), y2 - arrowSize * Math.sin(angle + Math.PI / 6));
    ctx.closePath();
    ctx.fill();
}

// --- Main Drawing ---

// Define coordinates for key elements
const y_axis_level = 150;
const O_x = 100;
const O_prime_x = 180;
const Q_x = 350;
const axis_end_x = 550;
const axis_top_y = 40;

// Draw horizontal axis (shared x and x' axis)
drawArrow(O_x - 50, y_axis_level, axis_end_x, y_axis_level);

// Draw S frame's y-axis
drawArrow(O_x, y_axis_level + 60, O_x, axis_top_y);

// Draw S' frame's y'-axis
drawArrow(O_prime_x, y_axis_level + 60, O_prime_x, axis_top_y);

// Draw labels for axes and origins
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillText('O', O_x, y_axis_level + 10);
ctx.fillText("O'", O_prime_x, y_axis_level + 10);

ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
ctx.fillText('y', O_x + 8, axis_top_y + 5);
ctx.fillText("y'", O_prime_x + 8, axis_top_y + 5);

ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillText('x', axis_end_x - 30, y_axis_level + 10);
ctx.fillText("x'", axis_end_x, y_axis_level + 10);

// Draw frame labels (S系 and S'系)
ctx.font = '24px "Times New Roman"';
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('S系', O_x - 40, y_axis_level - 5);
ctx.fillText("S'系", O_prime_x - 40, y_axis_level - 5);


// Draw particles P and Q
ctx.font = 'italic 22px "Times New Roman"'; // Reset font
const particleRadius = 4;

// Particle P (at O')
ctx.beginPath();
ctx.arc(O_prime_x, y_axis_level, particleRadius, 0, 2 * Math.PI);
ctx.fill();
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('P', O_prime_x, y_axis_level - 15);

// Particle Q
ctx.beginPath();
ctx.arc(Q_x, y_axis_level, particleRadius, 0, 2 * Math.PI);
ctx.fill();
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('Q', Q_x, y_axis_level - 15);
ctx.textBaseline = 'top';
ctx.fillText("x' = L", Q_x, y_axis_level + 10);


// Draw motion vectors and their labels
// Vector a₀ for particle P
const a0_start_x = O_prime_x + 15;
const a0_end_x = O_prime_x + 105;
drawArrow(a0_start_x, y_axis_level, a0_end_x, y_axis_level);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('a', (a0_start_x + a0_end_x) / 2 - 4, y_axis_level - 5);
ctx.font = 'italic 16px "Times New Roman"';
ctx.fillText('0', (a0_start_x + a0_end_x) / 2 + 8, y_axis_level - 5); // Subscript for 'a'
ctx.font = 'italic 22px "Times New Roman"'; // Reset font

// Vector u for particle Q
const u_start_x = Q_x + 15;
const u_end_x = Q_x + 105;
drawArrow(u_start_x, y_axis_level, u_end_x, y_axis_level);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('u', (u_start_x + u_end_x) / 2, y_axis_level - 5);

// Vector v for the S' frame's motion
const v_y = 90;
const v_start_x = 420;
const v_end_x = 520;
drawArrow(v_start_x, v_y, v_end_x, v_y);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.fillText('v', (v_start_x + v_end_x) / 2, v_y - 5);

</script>
</body>
</html>